package cn.shyouchi.wuguanjia.android.ui.event.labor;

import android.content.Intent;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.chad.library.adapter.base.entity.MultiItemEntity;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ColorTemplate;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cn.shyouchi.wuguanjia.android.R;
import cn.shyouchi.wuguanjia.android.api.event.EventApi;
import cn.shyouchi.wuguanjia.android.base.BaseActivity;
import cn.shyouchi.wuguanjia.android.chart.XAxisValueFormatter;
import cn.shyouchi.wuguanjia.android.chart.XYMarkerView;
import cn.shyouchi.wuguanjia.android.chart.YValue;
import cn.shyouchi.wuguanjia.android.chart.onYVlaueChangeListner;
import cn.shyouchi.wuguanjia.android.event.ApplyLaborEvent;
import cn.shyouchi.wuguanjia.android.model.BaseRequestResult;
import cn.shyouchi.wuguanjia.android.subscribers.ProgressSubscriber;
import cn.shyouchi.wuguanjia.android.utils.LogUtil;
import cn.shyouchi.wuguanjia.android.utils.ToastUtil;
import cn.shyouchi.wuguanjia.android.widget.TopBar;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class PersonLaborActivity extends BaseActivity implements onYVlaueChangeListner {

    @BindView(R.id.topBar)
    TopBar mTopBar;
    @BindView(R.id.rv_labor_list)
    RecyclerView mRvLaborList;
    @BindView(R.id.rv_apply_labor)
    RecyclerView mRvApplyLabor;
    PersonLaborAdapter mLaborAdapter;
    List<MultiItemEntity> mLaborEntities = new ArrayList<>();
    @BindView(R.id.btnPri)
    Button btnPri;
    @BindView(R.id.btnNext)
    Button btnNext;
    @BindView(R.id.tv_total_labor)
    TextView mTvTotalLabor;
    @BindView(R.id.tv_date)
    TextView mTvDate;
    @BindView(R.id.rank_chart)
    BarChart mBarChart;
    String projectId;
    EventApi mEventApi;
    Calendar mCalendar;
    BarDataSet set;
    List<YValue> yValueMap = new LinkedList<>();
    @BindView(R.id.tv_total_time)
    TextView mTvTotalTime;
    @BindView(R.id.tv_residual_time)
    TextView mTvResidualTime;
    @BindView(R.id.tv_total_person)
    TextView mTvTotalPerson;
    @BindView(R.id.tv_now_person)
    TextView mTvNowPerson;
    @BindView(R.id.pg_ranks)
    ViewPager mPgRanks;
    @BindView(R.id.activity_person)
    LinearLayout mActivityPerson;
    @BindView(R.id.img_item_expend_state)
    ImageView mExpendState;
    int days = 0;

    boolean added = false;


    List<PersonEntity> persons = new ArrayList<>();
    List<LaborRequestEntity.ResultMessageBean.ServiceBeanX> ranks = new ArrayList<>();
    ApplyLaborAdapter mApplyLaborAdapter;

    List<ApplyLaborEntity.ResultMessageBean> applylabors = new ArrayList<>();

    @Override
    public int initContentView() {
        return R.layout.activity_person_labor;
    }

    @Override
    public void initInjector() {
        projectId = getIntent().getStringExtra("projectId");
        mEventApi = new EventApi(mContext);
    }

    @Override
    public void initUiAndListener() {
        ButterKnife.bind(this);
        mTopBar.setTitle(getTitle().toString());
        mTopBar.setLeftIcon(R.mipmap.ic_back);
        setSupportActionBar(mTopBar.getToolbar());

        mApplyLaborAdapter = new ApplyLaborAdapter(applylabors);
        mRvApplyLabor.setLayoutManager(new LinearLayoutManager(mContext));
        mRvApplyLabor.setAdapter(mApplyLaborAdapter);

        EventBus.getDefault().register(this);

        mLaborAdapter = new PersonLaborAdapter(mLaborEntities, this);
//        for (int i = 0; i < 41; i++) {
//            PersonEntity personEntity = new PersonEntity("Eenie" + i);
//            mLaborEntities.add(personEntity);
//        }
        mRvLaborList.setLayoutManager(new LinearLayoutManager(mContext));
        mRvLaborList.setAdapter(mLaborAdapter);
        mCalendar = Calendar.getInstance();
        onMonthChange(mCalendar.getTime());


        mBarChart.setVisibleXRangeMaximum(5);//需要在设置数据源后生效
        mBarChart.setVisibleXRangeMinimum(5);//设置最少数量，不常用。
        mBarChart.setVisibleXRange(5, 6);

        XAxis xAxis = mBarChart.getXAxis();
        xAxis.setDrawGridLines(false);
        xAxis.setValueFormatter(new XAxisValueFormatter(yValueMap));
//        xAxis.setSpaceMax(0.1f);
//        xAxis.setSpaceMin(5f);
        xAxis.setGranularity(1f);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawLabels(true);
//        xAxis.setAxisMaximum(5f);
//        xAxis.setAxisMinimum(3f);


        YAxis axisRight = mBarChart.getAxisRight();
        axisRight.setDrawLabels(false);


        YAxis axisLeft = mBarChart.getAxisLeft();
        axisLeft.setLabelCount(6, false);
        axisLeft.setAxisMinimum(0f);
        axisLeft.setAxisMaximum(600f);
        axisLeft.setGranularityEnabled(false);
        axisLeft.setGranularity(0.1f);


        Legend legend = mBarChart.getLegend();
        legend.setEnabled(false);

//        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
//        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
//        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
//        legend.setDrawInside(false);
//        legend.setForm(Legend.LegendForm.CIRCLE);
//        legend.setFormSize(9f);
//        legend.setTextSize(11f);
//        legend.setXEntrySpace(4f);


        mBarChart.setTouchEnabled(true);
        mBarChart.setScaleEnabled(false);
        mBarChart.setDragEnabled(true);
        mBarChart.setDrawValueAboveBar(true);

        XYMarkerView mv = new XYMarkerView(this, new XAxisValueFormatter(yValueMap));
        mv.setChartView(mBarChart); // For bounds control
        mBarChart.setMarker(mv); // Set the marker to the chart

        btnPri.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCalendar.add(Calendar.MONTH, -1);
                onMonthChange(mCalendar.getTime());
            }
        });
        btnNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCalendar.add(Calendar.MONTH, 1);
                onMonthChange(mCalendar.getTime());
            }
        });


        refreshApply();
    }


    @Override
    protected boolean isApplyStatusBarTranslucency() {
        return false;
    }

    @Override
    protected boolean isApplyStatusBarColor() {
        return true;
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuItem menuItem = menu.add("保存");
        menuItem.setShowAsAction(2);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getTitle().equals("保存")) {
            generateEntityExit();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void generateEntityExit() {
        LogUtil.json(mLaborEntities);
        mEventApi.addPersonalHours(projectId, mLaborEntities, new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new ProgressSubscriber<BaseRequestResult>(mContext) {
                    @Override
                    public void onNext(BaseRequestResult result) {
                        ToastUtil.showToast("数据保存成功");
                    }
                });
    }


    private void onMonthChange(Date date) {


        for (int i = 0; i < mLaborAdapter.getData().size(); i++) {
            mLaborAdapter.collapse(i);
        }


        yValueMap.clear();
        mLaborEntities.clear();
        added = false;

        mTvDate.setText(new SimpleDateFormat("yyyy年MM月").format(date));
        mEventApi.getLaborUserList(projectId, new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Func1<AllotPersonEntity, List<PersonEntity>>() {
                    @Override
                    public List<PersonEntity> call(AllotPersonEntity allotPersonEntity) {
                        mTvTotalTime.setText(String.valueOf(allotPersonEntity.getHours().getWorkinghours()));
                        mTvResidualTime.setText(String.valueOf(allotPersonEntity.getHours().getRemaininghours()));
                        mTvTotalPerson.setText(String.valueOf(allotPersonEntity.getHours().getApproved()));
                        mTvNowPerson.setText(String.valueOf(allotPersonEntity.getHours().getActual()));
                        days = allotPersonEntity.getHours().getAttendance();
                        return allotPersonEntity.getResultMessage();
                    }
                })

                .subscribe(new Observer<List<PersonEntity>>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(List<PersonEntity> personEntities) {
                        persons.clear();
                        persons.addAll(personEntities);
                        ranks.clear();


                        mLaborEntities.addAll(personEntities);


                        for (PersonEntity entity : persons) {
                            entity.setDays(days);
                        }


                        mEventApi.getLaborList(projectId, new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()))
                                .subscribeOn(Schedulers.io())
                                .map(new Func1<LaborRequestEntity, List<LaborRequestEntity.ResultMessageBean>>() {
                                    @Override
                                    public List<LaborRequestEntity.ResultMessageBean> call(LaborRequestEntity laborRequestEntity) {
                                        return laborRequestEntity.getResultMessage();
                                    }
                                })
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Observer<List<LaborRequestEntity.ResultMessageBean>>() {
                                    @Override
                                    public void onCompleted() {

                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        e.printStackTrace();
                                    }

                                    @Override
                                    public void onNext(List<LaborRequestEntity.ResultMessageBean> resultMessageBeen) {

                                        ArrayList<BarEntry> yVals1 = new ArrayList<>();
                                        for (LaborRequestEntity.ResultMessageBean bean : resultMessageBeen) {

                                            if (!added) {
                                                ranks.addAll(bean.getService());
                                                added = true;
                                            }

                                            for (LaborRequestEntity.ResultMessageBean.ServiceBeanX rank : bean.getService()) {
                                                if (isExistRank(rank.getService().getId())) {
                                                    getYValueById(rank.getService().getId()).addCount(rank.getService_people());
                                                } else {
                                                    YValue y = new YValue();
                                                    y.setId(rank.getService().getId());
                                                    y.setName(rank.getService().getServicesname());
                                                    y.setStartTime(rank.getService().getStarttime());
                                                    y.setEndTime(rank.getService().getEndtime());
                                                    y.setInterval(rank.getService().getTime());
                                                    y.setCount(rank.getService_people());
                                                    yValueMap.add(y);
                                                }
                                            }
                                        }
                                        for (MultiItemEntity entity : mLaborEntities) {
                                            PersonEntity personEntity = (PersonEntity) entity;
                                            for (YValue y : yValueMap) {
                                                PersonLaborEntity p = new PersonLaborEntity(y);
                                                p.setTag(personEntity);
                                                personEntity.addSubItem(p);
                                            }
                                        }
                                        double time = 0d;
                                        int i = 0;
                                        for (YValue y : yValueMap) {
                                            i++;
                                            time = time + y.getTotalTime();

                                            yVals1.add(new BarEntry(i, (float) y.getCount()));
                                        }

//                                        set = new BarDataSet(yVals1, String.format("总工时：%.2f", time));
                                        set = new BarDataSet(yVals1, "");
                                        set.setValues(yVals1);
                                        set.setColors(ColorTemplate.MATERIAL_COLORS);
                                        set.setFormLineWidth(100f);

                                        BarData barData = new BarData(set);
                                        barData.setValueTextSize(10f);
                                        barData.setBarWidth(0.9f);
                                        mBarChart.setData(barData);

                                        Description des = new Description();
                                        des.setText(String.format("总工时：%.2f", time));
                                        mBarChart.setDescription(des);
                                        mBarChart.invalidate();
                                        mBarChart.animateY(500);
                                        mLaborAdapter.notifyDataSetChanged();
                                        /**
                                         * 分配工时
                                         */
                                        mEventApi.getPersonalHourslist(projectId, new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()))
                                                .subscribeOn(Schedulers.io())
                                                .flatMap(new Func1<PersonRank, Observable<PersonRank.ResultMessageBean>>() {
                                                    @Override
                                                    public Observable<PersonRank.ResultMessageBean> call(PersonRank personRank) {

                                                        LogUtil.json(personRank);

//                                                        mTvTotalTime.setText(String.valueOf(personRank.getHours().getWorkinghours()));
//                                                        mTvResidualTime.setText(String.valueOf(personRank.getHours().getRemaininghours()));
//                                                        mTvTotalPerson.setText(String.valueOf(personRank.getHours().getApproved()));
//                                                        mTvNowPerson.setText(String.valueOf(personRank.getHours().getActual()));
                                                        return Observable.from(personRank.getResultMessage());
                                                    }
                                                })
                                                .observeOn(AndroidSchedulers.mainThread())
                                                .subscribe(new Observer<PersonRank.ResultMessageBean>() {
                                                    @Override
                                                    public void onCompleted() {
                                                        mLaborAdapter.notifyDataSetChanged();


                                                    }

                                                    @Override
                                                    public void onError(Throwable e) {
                                                        e.printStackTrace();
                                                    }

                                                    @Override
                                                    public void onNext(PersonRank.ResultMessageBean personRank) {
                                                        PersonEntity person = getPersonById(personRank.getUser_id());
                                                        person.setDays(days);
                                                        if (person != null) {
                                                            for (PersonRank.ResultMessageBean.InfoBean info : personRank.getInfo()) {
                                                                for (PersonLaborEntity entity : person.getSubItems()) {
                                                                    if (entity.getId() == info.getService().getId()) {
                                                                        entity.setCount(info.getDay());
                                                                        onChange(info.getService().getId(), info.getDay());
                                                                        break;
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                });
                                    }
                                });
                    }
                });
    }


    public PersonEntity getPersonById(int id) {
        for (MultiItemEntity entity : mLaborEntities) {
            if (entity instanceof PersonEntity) {
                PersonEntity personEntity = (PersonEntity) entity;
                if (personEntity.getId() == id) {
                    return personEntity;
                }
            }
        }
        return null;
    }


    @Override
    public boolean isCanChange(float xValue) {
        return mBarChart.getBarData().getDataSets().get(0).getEntriesForXValue(getYValuePosition((int) xValue)).get(0).getY() > 0;
    }

    @Override
    public boolean onChange(float xValue, float yValue) {

        float y = mBarChart.getBarData().getDataSets().get(0).getEntriesForXValue(getYValuePosition((int) xValue)).get(0).getY();
        mBarChart.getBarData().getDataSets().get(0).getEntriesForXValue(getYValuePosition((int) xValue)).get(0).setY(y - yValue);
        mBarChart.invalidate();
        return false;
    }


    public boolean isExistRank(int rankId) {
        for (YValue y : yValueMap) {
            if (y.getId() == rankId) {
                return true;
            }
        }
        return false;
    }

    public YValue getYValueById(int rankId) {
        for (YValue y : yValueMap) {
            if (y.getId() == rankId) {
                return y;
            }
        }
        return null;
    }

    public int getYValuePosition(int rankId) {
        int i = 0;
        for (YValue y : yValueMap) {
            i++;
            if (y.getId() == rankId) {
                return i;
            }
        }
        return i;
    }


    @OnClick(R.id.tv_apply_labor)
    public void onClick() {
        Intent intent = new Intent(mContext, ApplyLaborActivity.class);
        intent.putParcelableArrayListExtra("persons", (ArrayList<? extends Parcelable>) persons);
        intent.putParcelableArrayListExtra("ranks", (ArrayList<? extends Parcelable>) ranks);
        intent.putExtra("projectId", projectId);
        intent.putExtra("date", new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()));
        startActivity(intent);
    }

    @OnClick(R.id.item_apply)
    public void onItemClick() {


        mRvApplyLabor.setVisibility(mRvApplyLabor.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
        mExpendState.setImageResource(mRvApplyLabor.getVisibility() == View.VISIBLE ? R.mipmap.ic_item_group_open : R.mipmap.ic_item_group_close);


    }


    public void refreshApply() {
        mEventApi.getApplyLborList(projectId, new SimpleDateFormat("yyyy-MM-dd").format(mCalendar.getTime()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ApplyLaborEntity>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(ApplyLaborEntity entity) {
                        applylabors.clear();
                        applylabors.addAll(entity.getResultMessage());
                        mApplyLaborAdapter.notifyDataSetChanged();
                    }
                });
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onApplyLaborChange(ApplyLaborEvent event) {
        refreshApply();
    }


    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
